package com.example.netty.encode.Packet;

import com.example.netty.encode.command.Command;
import com.example.netty.encode.serializer.JSONSerializer;
import com.example.netty.encode.serializer.Serializer;
import io.netty.buffer.ByteBuf;

import java.util.HashMap;
import java.util.Map;

/** 编码解码器
 * @author liupk
 * @date 2018/10/24
 */
public class PackerCode {
    
    public static final int MAGIC_NUMBER = 0x12345678;
    private  final Map<Byte, Class<? extends Packet>> packetTypeMap;
    private  final Map<Byte, Serializer> serializerMap;
    
    
    private static PackerCode INSTANCE = null;
    private PackerCode(){
        packetTypeMap = new HashMap<>();
        packetTypeMap.put(Command.LOGIN_REQUEST, LoginRequestPacket.class);
        packetTypeMap.put(Command.LOGIN_RESPONSE, LoginResponsePacket.class);
        packetTypeMap.put(Command.MESSAGE_REQUEST, MessageRequestPacket.class);
        packetTypeMap.put(Command.MESSAGE_RESPONSE, MessageResponsePacket.class);
        serializerMap = new HashMap<>();
        Serializer serializer = new JSONSerializer();
        serializerMap.put(serializer.getSerializerAlgorithm(), serializer);
    }
    
    public static PackerCode getINSTANCE() {
        if (null == INSTANCE){
            return new PackerCode();
        }
        return INSTANCE;
    }
    
    static {
    
    }
    /**
     * 编码
     * @date 2018/10/24
     * @param
     * @return
     */
    public ByteBuf encode(ByteBuf byteBuf,Packet packet){
        /**序列化packet对象*/
        byte[] bytes = Serializer.DEFAULT.serialize(packet);
        /**写入数据*/
        byteBuf.writeInt(MAGIC_NUMBER);
        byteBuf.writeByte(packet.getVersion());
        byteBuf.writeByte(Serializer.DEFAULT.getSerializerAlgorithm());
        byteBuf.writeByte(packet.getCommand());
        byteBuf.writeInt(bytes.length);
        byteBuf.writeBytes(bytes);
        
        return byteBuf;
    }
    
    /**
     * 解码
     * @date 2018/10/24
     * @param
     * @return
     */
    public Packet decode(ByteBuf byteBuf){
        /**跳过魔数*/
        byteBuf.skipBytes(4);
        /**跳过版本号*/
        byteBuf.skipBytes(1);
        /**获取序列化算法*/
        byte serializeAlgorithm = byteBuf.readByte();
        /**指令*/
        byte command = byteBuf.readByte();
        /**数据包长度*/
        int lenght = byteBuf.readInt();
        
        byte[] bytes = new byte[lenght];
        byteBuf.readBytes(bytes);
    
        Class<? extends Packet> requestType = getRequestType(command);
        Serializer serializer = getSerializer(serializeAlgorithm);
        
        if (null != requestType && null != serializer){
           return serializer.deserialize(requestType,bytes);
        }
        return null;
    }
    
    private Serializer getSerializer(byte serializeAlgorithm) {
        
        return serializerMap.get(serializeAlgorithm);
    }
    
    private Class<? extends Packet> getRequestType(byte command) {
        
        return packetTypeMap.get(command);
    }
}